import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;



public class Save {
    /**
     * 游戏存档类,鲁滨逊与星期五单独存档.
     */
    static List<Robinson> robinsonList = new ArrayList<>();
    static List<Friday> fridayList = new ArrayList<>();

    static int index = 0;

    /**
     * 新存档,将鲁滨逊和星期五的实例添加到存档列表中.
     * 存档编号index存储在robinson中.
     * 即将存档列表中的实例存储到saved目录下的文件中.
     *
     * @param robinson  鲁滨逊实例
     * @param friday    星期五实例
     */
    public static void save(Robinson robinson, Friday friday) {
        Robinson robinson1 = new Robinson(robinson);
        Friday friday1 = new Friday(friday);
        robinsonList.add(robinson1);
        fridayList.add(friday1);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  // 设置日期格式
        robinsonList.get(robinsonList.size() - 1).time = df.format(new Date());  // 获取当前时间存储到鲁滨逊的time属性中
        for (Robinson value : robinsonList) {
            System.out.println(value.getStrength());
        }
        index ++;

        JSONArray jsonArrayOfRobinson = JSONArray.fromObject(robinsonList);  // robinsonList的json字符串
        JSONArray jsonArrayOfFriday = JSONArray.fromObject(fridayList);  // fridayList的json字符串
        saveLocally(jsonArrayOfRobinson.toString(),  "./saved/savedRobinson.json");  // 生成json文件保存到saved目录下
        saveLocally(jsonArrayOfFriday.toString(),  "./saved/savedFriday.json");
    }
    /**
     * 存档:生成一个json文件存到本地.
     * 返回一个boolean值表明是否生成成功.
     *
     * @param jsonString     json文件的字符串
     * @param fileName      文件名
     */
    public static void saveLocally(String jsonString, String fileName) {
            try {
            File file = new File(fileName);

            if (!file.exists()) {  // 如果不存在,创建一个新文件。一般来说一台电脑只有在第一次save才会用到。以后每一次存档都会重新写这个文件。
                file.createNewFile();
            }

            if(jsonString.contains("'")){  // 如果jsonString中包含单引号，则转义，因为JSON串中的字符串类型可以单引号引起
                jsonString = jsonString.replaceAll("'", "\\'");
            }
            if(jsonString.contains("\"")){  // 如果jsonString中包含双引号，则转义，因为JSON串中的字符串类型可以双引号引起
                jsonString = jsonString.replaceAll("\"", "\\\"");
            }
            if(jsonString.contains("\r\n")){ // 如果jsonString中包含回车换行，则进行转换，因为JSON串中字符串不能出现显式的回车换行
                jsonString = jsonString.replaceAll("\r\n", "\\u000d\\u000a");
            }
            if(jsonString.contains("\n")){ // 如果jsonString中包含换行，则进行转换，因为JSON串中字符串不能出现显式的换行
                jsonString = jsonString.replaceAll("\n", "\\u000a");
            }

            jsonString = formatJson(jsonString);

            // 将格式化后的字符串写入文件
            Writer write = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            write.write(jsonString);
            write.flush();
            write.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回格式化JSON字符串.
     *
     * @param json 未格式化的JSON字符串
     * @return 格式化的JSON字符串
     */
    public static String formatJson(String json) {
        StringBuffer result = new StringBuffer();

        int length = json.length();
        int number = 0; //
        char key = 0;

        for (int i = 0; i < length; i++) {
            key = json.charAt(i); // 获取当前字符
            if ((key == '[') || (key == '{')) { // 如果当前字符是前方括号、前花括号
                if ((i - 1 > 0) && (json.charAt(i - 1) == ':')) { // 如果前面还有字符，并且字符为“：”，打印：换行和缩进字符字符串
                    result.append('\n');
                    result.append(indent(number));
                }
                result.append(key); // 打印：当前字符
                result.append('\n'); // 前方括号、前花括号，的后面必须换行
                number++;  // 每出现一次前方括号、前花括号；缩进次数增加一次
                result.append(indent(number));
                continue;
            }

            if ((key == ']') || (key == '}')) {  // 如果当前字符是后方括号、后花括号做如下处理：
                result.append('\n'); // 后方括号、后花括号，的前面必须换行。打印：换行。
                number--; // 每出现一次后方括号、后花括号；缩进次数减少一次。打印：缩进。
                result.append(indent(number));
                result.append(key); // 打印：当前字符
                if (((i + 1) < length) && (json.charAt(i + 1) != ',')) { // 如果当前字符后面还有字符，并且字符不为“，”，打印：换行。
                    result.append('\n');
                }
                continue;
            }

            if ((key == ',')) { // 如果当前字符是逗号。逗号后面换行，并缩进，不改变缩进次数。
                result.append(key);
                result.append('\n');
                result.append(indent(number));
                continue;
            }
            result.append(key); // 打印：当前字符。
        }

        return result.toString();
    }

    /**
     * 返回指定次数的缩进字符串,每一次缩进三个空格.
     *
     * @param number 缩进次数
     * @return 指定缩进次数的字符串
     */
    private static String indent(int number) {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < number; i++) {
            result.append("   ");
        }
        return result.toString();
    }

    /**
     * 读档:读取saved目录下的json文档,得到robinsonList和fridayList.
     */
    public static void read(){

        InputStream robinsonStream = Save.class.getResourceAsStream("saved/savedRobinson.json");
        InputStream fridayStream = Save.class.getResourceAsStream("saved/savedFriday.json");


        BufferedReader readerOfRobinson = null;
        String robinsonString = "";
        try{
            InputStreamReader inputStreamReader = new InputStreamReader(robinsonStream, StandardCharsets.UTF_8);
            readerOfRobinson = new BufferedReader(inputStreamReader);
            String tempString = null;
            while((tempString = readerOfRobinson.readLine()) != null){
                robinsonString += tempString;
            } // 一行行读取
            readerOfRobinson.close();

            JSONArray jsonArrayOfRobinson = JSONArray.fromObject(robinsonString);
            for(int i = 0; i < jsonArrayOfRobinson.size(); i++){
                JSONObject jsonObjectOfRobinson = jsonArrayOfRobinson.getJSONObject(i);
                Robinson robinson = new Robinson();  // 按照json文件中的数据重新初始化一个robinson对象,并添加到robinsonList中
                robinson.setAge(jsonObjectOfRobinson.getInt("age"));
                robinson.setAlert(jsonObjectOfRobinson.getBoolean("alert"));
                robinson.setDate_on_island(jsonObjectOfRobinson.getInt("date_on_island"));
                robinson.setIndex(jsonObjectOfRobinson.getInt("index"));
                robinson.setIntelligence(jsonObjectOfRobinson.getDouble("intelligence"));  // 如果json里面是一个整型就会报错,但是大概率不会发生
                robinson.setMood(jsonObjectOfRobinson.getDouble("mood"));
                robinson.setStrength(jsonObjectOfRobinson.getDouble("strength"));
                robinson.setFlag(jsonObjectOfRobinson.getInt("flag"));
                robinson.setRescued(jsonObjectOfRobinson.getBoolean("rescued"));
                robinson.setLive(jsonObjectOfRobinson.getBoolean("live"));
                robinson.setGotFriday(jsonObjectOfRobinson.getBoolean("gotFriday"));
                robinson.setSailing_time(jsonObjectOfRobinson.getInt("sailing_time"));
                robinson.setSheep_amount(jsonObjectOfRobinson.getInt("sheep_amount"));
                robinson.setWoodworking_time(jsonObjectOfRobinson.getInt("woodworking_time"));
                robinson.setCrops_amount(jsonObjectOfRobinson.getInt("crops_amount"));
                robinson.setTime(jsonObjectOfRobinson.getString("time"));

                robinsonList.add(robinson);
                index ++;  // 此处参数增加,在读取星期五数据时就不加了.
            }

        }catch(IOException e){
            e.printStackTrace();
        }finally{
            if(readerOfRobinson != null){
                try {
                    readerOfRobinson.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        BufferedReader readerOfFriday = null;
        StringBuilder fridayString = new StringBuilder();
        try{

            InputStreamReader inputStreamReader = new InputStreamReader(fridayStream, StandardCharsets.UTF_8);
            readerOfFriday = new BufferedReader(inputStreamReader);
            String tempString ;
            while((tempString = readerOfFriday.readLine()) != null){
                fridayString.append(tempString);
            } // 一行行读取
            readerOfFriday.close();

            JSONArray jsonArrayOfFriday = JSONArray.fromObject(fridayString.toString());
            for(int i = 0; i < jsonArrayOfFriday.size(); i++){
                JSONObject jsonObjectOfFriday = jsonArrayOfFriday.getJSONObject(i);
                Friday friday = new Friday(3);
                String s = jsonObjectOfFriday.get("is_work").toString();
                ArrayList<Integer> list = new ArrayList<>();
                for(int j = 0; j < s.length(); j++){
                    if(s.charAt(j) == ',' || s.charAt(j) == '['){
                        for(int k = j + 1; ; k++){
                            if(s.charAt(k) == ',' || s.charAt(k) == ']'){
                                String s1 = s.substring(j+1, k);
                                if(s1.equals("")) break;
                                int x = Integer.parseInt(s1);
                                list.add(x);
                                break;
                            }
                        }
                    }
                }
                friday.setIs_work(list);
                friday.setObedience(jsonObjectOfFriday.getInt("obedience"));
                friday.setStrength(jsonObjectOfFriday.getInt("strength"));
                fridayList.add(friday);
            }

        }catch(IOException e){
            e.printStackTrace();
        }finally{
            if(readerOfFriday != null){
                try {
                    readerOfFriday.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除存档:删除列表中的鲁滨逊和星期五实例,并生成新的json文件.
     * @param index1 被删除的鲁滨逊实例在列表中的位置
     */
    public static void deleteRecord(int index1) {
        robinsonList.remove(index1);
        fridayList.remove(index1);
        index --;
        JSONArray jsonArrayOfRobinson = JSONArray.fromObject(robinsonList); // robinsonList的json字符串
        JSONArray jsonArrayOfFriday = JSONArray.fromObject(fridayList); // fridayList的json字符串
        saveLocally(jsonArrayOfRobinson.toString(),  "./saved/savedRobinson.json"); // 生成json文件保存到saved目录下
        saveLocally(jsonArrayOfFriday.toString(),  "./saved/savedFriday.json");
    }
}

